import { constantRoutes } from '@/router'
import { getRouters } from '@/api/menu'
import Layout from '@/layout/index'
import ParentView from '@/components/ParentView';
import { toCamelCase } from "@/utils";

const permission = {
  state: {
    routes: [],
    addRoutes: [],
    sidebarRouters: [], // 左侧边菜单的路由，被 Sidebar/index.vue 使用
    topbarRouters: [], // 顶部菜单的路由，被 TopNav/index.vue 使用
    topUserRouters: [], // 顶部用户下拉选择项中菜单导航，被 Navbar.vue 使用
  },
  mutations: {
    SET_ROUTES: (state, routes) => {
      state.addRoutes = routes
      state.routes = constantRoutes.concat(routes)
    },
    SET_DEFAULT_ROUTES: (state, routes) => {
      state.defaultRoutes = constantRoutes.concat(routes)
    },
    SET_TOPBAR_ROUTES: (state, routes) => {
      state.topbarRouters = routes
    },
    SET_SIDEBAR_ROUTERS: (state, routes) => {
      state.sidebarRouters = routes
    },
    SET_TOP_USER_ROUTES: (state, routes) => {
      state.topUserRouters = routes;
    },
  },
  actions: {
    // 生成路由
    GenerateRoutes({ commit }) {
      return new Promise(resolve => {
        // 向后端请求路由数据（菜单）
        getRouters().then(res => {
          console.log(res);
          const sdata = JSON.parse(JSON.stringify(res.data)) // 【重要】用于菜单中的数据
          const rdata = JSON.parse(JSON.stringify(res.data)) // 用于最后添加到 Router 中的数据
          // const sidebarRoutes = filterAsyncRouter(sdata)
          const rewriteRoutes = filterAsyncRouter(rdata, false, true)
          rewriteRoutes.push({ path: '*', redirect: '/404', hidden: true })
          commit('SET_ROUTES', rewriteRoutes)
          // commit('SET_SIDEBAR_ROUTERS', constantRoutes.concat(sidebarRoutes))

          const defaultRoutes = filterPositionRouter(sdata, null, true);
          const sidebarRoutes = filterAsyncRouter(defaultRoutes); // 左侧边菜单
          const topData = JSON.parse(JSON.stringify(res.data))
          const topUserRoutes = filterPositionRouter(topData, 1, true); // 顶部用户下拉选择项中菜单导航

          commit('SET_SIDEBAR_ROUTERS', constantRoutes.concat(sidebarRoutes))
          commit('SET_DEFAULT_ROUTES', sidebarRoutes)
          commit('SET_TOPBAR_ROUTES', sidebarRoutes)

          commit('SET_TOP_USER_ROUTES', filterAsyncRouter(topUserRoutes));
          resolve(rewriteRoutes)
        })
      })
    }
  }
}

// 遍历路由组件对象，找出特定位置的菜单项。默认为 null 和上一级保持一致。一级默认是侧边栏
function filterPositionRouter(asyncRouterMap, routePosition = null, isFirstLevel = false) {
  return asyncRouterMap.filter((route) => {
    // 默认路由，直接返回
    if (route.position === null && routePosition === null) {
      return true;
    }
    // 子路由默认值时，直接返回
    if (route.position === null && routePosition !== null && !isFirstLevel) {
      return true;
    }
    // 路由设置了具体位置，判断位置是否匹配
    if (route.position == routePosition) {
      // 当前路由是该分类下的路由菜单，则判断子路由是否都匹配
      if (route.children != null && route.children && route.children.length) {
        route.children = filterPositionRouter(route.children, routePosition, false)
      }
      return true
    }
    return false;
  })
}

// 遍历后台传来的路由字符串，转换为组件对象
function filterAsyncRouter(asyncRouterMap, lastRouter = false, type = false) {
  return asyncRouterMap.filter((route) => {
    // 将 ruoyi 后端原有耦合前端的逻辑，迁移到此处
    // 处理 meta 属性
    route.meta = {
      title: route.name,
      icon: route.icon,
      noCache: !route.keepAlive,
    }
    route.hidden = !route.visible;
    // 路由地址转首字母大写驼峰，作为路由名称，适配 keepAlive
    const path = (lastRouter ? lastRouter.path + '/' : '') + route.path;
    route.name = toCamelCase(path.replace(/\//g, '-'), true);
    // 处理 component 属性
    if (route.children) { // 父节点
      if (route.parentId === 0) {
        route.component = Layout
      } else {
        route.component = ParentView
      }
    } else { // 根节点
      route.component = loadView(route.component)
    }

    // filterChildren
    if (type && route.children) {
      route.children = filterChildren(route.children)
    }
    if (route.children != null && route.children && route.children.length) {
      route.children = filterAsyncRouter(route.children, route, type)
    } else {
      delete route['children']
    }
      return true
  })
}

/**
 * filterChildren 函数用于过滤并获取所有子路由，将它们拼接为全路径。
 * 当且仅当 el.component 不存在，且 el.children 存在时，递归调用 filterChildren 函数才真正有效。
 *
 * @param {Object} childrenMap - 包含路由信息的对象。
 * @param {Object} [lastRouter=false] - 上一个路由对象，默认为false。
 * @returns {Array} 返回所有子路由的数组。
 */
function filterChildren(childrenMap, lastRouter = false) {
  let children = []
  childrenMap.forEach((el, index) => {
    // 如果当前路由对象包含子路由。
    if (el.children && el.children.length) {
      // 如果当前路由对象没有组件设置并且不是最后一级路由。
      if (!el.component && !lastRouter) {
        // 遍历当前路由对象的子路由。
        el.children.forEach(c => {
          c.path = el.path + '/' + c.path
          if (c.children && c.children.length) {
            children = children.concat(filterChildren(c.children, c))
            return
          }
          children.push(c)
        })
        return
      }
    }
    // 如果不是一级路由。
    if (lastRouter) {
      // 将当前路由的路径与上一个路由的路径拼接。
      el.path = lastRouter.path + "/" + el.path;
    }
    children = children.concat(el);
  })
  return children
}

export const loadView = (view) => { // 路由懒加载
  return (resolve) => require([`@/views/${view}`], resolve)
}

export default permission
